package instant.lang.test;

import org.junit.jupiter.api.Test;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.stream.IntStream;

public class ReferenceTestCase {


    /**
     * WeakReference弱引用不影响对象的回收
     */
    @Test
    public void testWeakReference() {
        Object o = new Object();
        WeakReference<Object> wo = new WeakReference<>(o);
        while(wo.get() != null) {
            System.out.println("object exists");
            o = null;
            System.out.println(wo.get());
            System.gc();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }



    @Test
    public void testWeakRef() {
        WeakA a = new WeakA();
        a.setB();
        System.out.println(a.getB());   // not exists
    }

    @Test
    public void testSoftRef() {
        SoftA a = new SoftA();
        a.setB();
        System.out.println(a.getB());   // exists
    }

    public static class WeakA {
        private WeakReference<B> b;

        public void setB() {
            B bb = new B();
            b = new WeakReference<>(bb);
        }

        public B getB() {
            System.gc();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return b.get();
        }
    }

    public static class B {}

    public static class SoftA {
        private SoftReference<B> b;

        public void setB() {
            B bb = new B();
            b = new SoftReference<>(bb);
        }

        public B getB() {
            System.gc();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return b.get();
        }
    }

    @Test
    public void testWeakHashMap() {
        WeakHashMapA a = new WeakHashMapA();
        a.setMap();
        System.out.println(a.getMap());   // not exists
    }

    public static class WeakHashMapA {
        Map<B, Integer> map = new WeakHashMap<>();

        public void setMap() {
            IntStream.range(1, 10).boxed().forEach(k -> map.put(new B(), k));
        }

        public Map<B, Integer> getMap() {
            System.gc();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return map;
        }
    }

}
